home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Delete.c -- for BlackHole.c.
- * $Revision: 1.1
- */
-
- #include "header.h"
- #include "prog-protos.h"
-
- /* Prototypes */
- Prototype LONG delete (struct HoleArg *);
-
- Local LONG delete_file (struct WBArg *);
- Local LONG delete_icon (struct WBArg *);
- Local LONG delete_dir (struct WBArg *);
- Local LONG delete_contents (BPTR , BOOL );
-
- /* Globals */
- BOOL ignore_protection;
-
- #define EXALL_NUM 16 /* examine 16 files at a time (I think) */
-
- /* Entry point */
- LONG delete (struct HoleArg *harg)
- {
- set_current (NULL, SET_START); /* reset current file */
- ignore_protection = harg->prefs.ignore_prot;
- return (delete_file (&(harg->wbarg)));
- }
-
- /* Local functions */
-
- /* delete_contents -- delete the contents of a directory with lock lock. */
- /* If byicons is FALSE, search for ~(#?.info) & delete both name found and */
- /* name.info, if byicons is true, delete any file of pattern #?.info */
- LONG delete_contents (BPTR lock, BOOL byicons)
- {
- BPTR old_lock = CurrentDir (lock);
-
- struct ExAllControl *eac = 0;
- struct ExAllData *eadata = 0;
- struct WBArg *arg = 0;
- LONG error = 0;
- BOOL more;
- BYTE pattern[50];
-
- if (!(eac = (struct ExAllControl *) AllocDosObject (DOS_EXALLCONTROL, NULL)))
- goto fail;
- if (!(eadata = (struct ExAllData *)
- malloc (EXALL_NUM * sizeof (struct ExAllData)))) goto fail;
- if (!(arg = (struct WBArg *)malloc (sizeof (struct WBArg)))) goto fail;
-
- if (byicons) ParsePatternNoCase ("#?.info", pattern, 49);
- else ParsePatternNoCase ("~(#?.info)", pattern, 49);
-
- eac->eac_LastKey = 0;
- eac->eac_MatchString = pattern;
- eac->eac_MatchFunc = NULL;
-
- do {
- register struct ExAllData *ead;
-
- more = ExAll (lock, eadata, EXALL_NUM * sizeof (struct ExAllData),
- ED_TYPE, eac);
- if (!more)
- {
- if ((error = IoErr()) != ERROR_NO_MORE_ENTRIES) break;
- else error = 0;
- }
-
- if (eac->eac_Entries == 0) continue; /* have we finished? */
-
- ead = eadata;
-
- do {
- if (ead->ed_Type >=0) /* is it a directory? */
- {
- arg->wa_Lock = Lock (ead->ed_Name, SHARED_LOCK);
- arg->wa_Name = NULL;
- if (arg->wa_Lock)
- {
- if (error = delete_file (arg))
- {
- more = FALSE; break;
- UnLock (arg->wa_Lock);
- }
- }
- }
- else /* it must be a file. */
- {
- arg->wa_Lock = lock;
- arg->wa_Name = ead->ed_Name;
-
- if (byicons)
- {
- if (error = delete_icon (arg))
- {
- more = FALSE; break;
- }
- }
- else
- {
- if (error = delete_file (arg))
- {
- more = FALSE; break;
- }
- }
- }
- } while (ead = ead->ed_Next); /* go to next entry */
-
- } while (more); /* take next read from ExAll */
-
- fail:
-
- if (arg) free (arg);
- else error = ERROR_NO_FREE_STORE;
- if (eadata) free (eadata);
- if (eac) FreeDosObject (DOS_EXALLCONTROL, eac);
- CurrentDir (old_lock);
-
- return (error);
- }
-
-
- /* delete_dir -- delete a directory from lock. lock MUST be a directory */
- /* or else! Returns an error from IoErr(), or 0 for ok. */
- LONG delete_dir (struct WBArg *wa)
- {
- LONG error = 0;
- char buf[256];
- struct WBArg *parent = 0;
-
- if (error = delete_contents (wa->wa_Lock, FALSE)) goto fail; /* delete files with/without icons */
- if (error = delete_contents (wa->wa_Lock, TRUE)) goto fail; /* delete any lone .info files */
- if (!(parent = (struct WBArg *)malloc (sizeof (struct WBArg)))) goto fail;
-
- if (parent->wa_Lock = ParentDir (wa->wa_Lock))
- {
- if (NameFromLock (wa->wa_Lock, buf, 254))
- {
- UnLock (wa->wa_Lock); /* UnLock the dir as it is about to be deleted */
- wa->wa_Lock = NULL; /* Tell everyone we've unlocked it. */
-
- parent->wa_Name = FilePart (buf);
- set_current (NULL, SET_EXIT_DIR);
- error = delete_file (parent); /* delete ourselves */
- if (error) /* if failed, restore lock to directory */
- {
- BPTR olddir = CurrentDir (parent->wa_Lock);
- wa->wa_Lock = Lock (parent->wa_Name, SHARED_LOCK); /* fingers crossed! */
- CurrentDir (olddir);
- }
- } else error = IoErr();
- UnLock (parent->wa_Lock);
- }
- else error = IoErr();
-
- fail:
-
- if (parent) free (parent);
-
- return (error);
- }
-
- /* delete_icon -- delete an icon with name (MUST have a .info extension) */
- /* which lives in dir locked in lock */
- LONG delete_icon (struct WBArg *wa)
- {
- LONG error = 0;
- char *dot;
-
- if (error = set_current (wa, SET_NEWFILE)) goto fail;
-
- if (dot = strrchr (wa->wa_Name, '.'))
- {
- *dot = '\0'; /* temporarily remove .info extension */
- error = delete_file (wa);
- *dot = '.'; /* restore .info, in case it is needed later */
- }
- else error = ERROR_OBJECT_WRONG_TYPE;
-
- fail:
-
- return (error);
- }
-
- /* delete_file -- delete a file or dir given a lock to the dir + a name */
- /* Returns an error code from IoErr() if failed, or 0 for ok. */
- LONG delete_file (struct WBArg *wa)
- {
- LONG error = 0;
- BOOL nofile = FALSE;
-
- if (error = set_current (wa, SET_NEWFILE)) goto fail;
-
- if ((wa->wa_Name[0] == '\0') || !(wa->wa_Name)) /* is it a directory? */
- {
- error = delete_dir (wa);
- }
- else
- {
- /* cd to lock and store old lock */
- BPTR old_lock = CurrentDir (wa->wa_Lock);
-
- if (!DeleteFile (wa->wa_Name)) /* if delete file fails */
- {
- error = IoErr();
-
- if ((error == ERROR_DELETE_PROTECTED) && ignore_protection)
- {
- error = 0;
- if (SetProtection (wa->wa_Name, 0))
- { /* try again to delete it */
- if (!DeleteFile (wa->wa_Name)) error = IoErr();
- }
- else error = IoErr();
- }
-
- if (error == ERROR_OBJECT_NOT_FOUND)
- {
- error = 0;
- nofile = TRUE; /* object is just an icon */
- }
- }
-
- if (!error)
- {
- char dotinfo[100];
- strcpy (dotinfo, wa->wa_Name);
- strcat (dotinfo, ".info"); /* create name of icon */
-
- if (!DeleteDiskObject (wa->wa_Name)) /* delete icon */
- {
- error = IoErr();
-
- if ((error == ERROR_DELETE_PROTECTED) && ignore_protection)
- {
- error = 0;
- if (SetProtection (dotinfo, 0))
- { /* try again */
- if (!DeleteDiskObject (wa->wa_Name)) error = IoErr();
- }
- else error = IoErr();
- }
-
- /* If no icon was found and there was a file that was deleted */
- if ((error == ERROR_OBJECT_NOT_FOUND) && !nofile)
- {
- BPTR fh = Open (dotinfo, MODE_NEWFILE); /* make pseudo icon */
- if (fh)
- {
- Close (fh);
- if (!DeleteDiskObject (wa->wa_Name)) /* now delete it! */
- error = IoErr();
- else error = 0;
- }
- else error = IoErr();
- }
- }
- }
- CurrentDir (old_lock); /* restore old cd */
- }
-
- fail:
-
- return (error);
- }
-
-